﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using XcoAppSpaces.Contracts.Messaging;
using XcoAppSpaces.Contracts.Worker;
using XcoAppSpaces.Contracts.PortWiring;
using XcoAppSpaces.Core;
using XcoAppSpaces.Core.Ports;
using XcoAppSpaces.Contracts.Exceptions;

namespace test.XcoAppSpaces.Core
{
	[TestFixture]
	public class testLocalWorkerRegistry
	{
		private LocalWorkerRegistry workerRegistry;

		[SetUp]
		public void SetUp()
		{
			workerRegistry = new LocalWorkerRegistry();
		}

		[TearDown]
		public void TearDown()
		{
		}

		[Test]
		public void TestExists_NoWorker()
		{
			bool exists = workerRegistry.Exists("bla", false, false);
			Assert.IsFalse(exists);
		}

		[Test]
		public void TestExists_WorkerWithoutName()
		{
			workerRegistry.Register<WorkerContract>(new WorkerContract(), null);
			bool exists = workerRegistry.Exists("test.XcoAppSpaces.Core.WorkerContract", false, false);
			Assert.IsTrue(exists);
		}

		[Test]
		public void TestExists_WorkerWithName()
		{
			workerRegistry.Register<WorkerContract>(new WorkerContract(), "bla");
			bool exists = workerRegistry.Exists("test.XcoAppSpaces.Core.WorkerContract/bla", false, false);
			Assert.IsTrue(exists);
		}

		[Test]
		public void TestExists_WorkerProxy_CorrectId()
		{
			workerRegistry.AddWorkerProxy<WorkerContract>(new WorkerContract(), "bla", PublishMode.Published, "adr", new WorkerProxyInfo(null, null, null, "myid", null, Guid.Empty, null, null));
			bool exists = workerRegistry.Exists("test.XcoAppSpaces.Core.WorkerContract/bla", true, false);
			Assert.IsTrue(exists);
		}

		[Test]
		public void TestExists_WorkerProxy_WrongId()
		{
			workerRegistry.AddWorkerProxy<WorkerContract>(new WorkerContract(), "bla", PublishMode.Unpublished, null, new WorkerProxyInfo(null, null, null, "myid", null, Guid.Empty, null, null));
			bool exists = workerRegistry.Exists("myid", true, false);
			Assert.IsFalse(exists);
		}

		[Test]
		public void TestNumberOfConnectCalls()
		{
			workerRegistry.AddWorkerProxy<WorkerContract>(new WorkerContract(), "bla", PublishMode.Published, null, new WorkerProxyInfo(null, null, null, "myid", null, Guid.Empty, null, null));
			Assert.AreEqual(1, workerRegistry.Workers.Count());
			//number of connect calls should not be increased
			workerRegistry.Exists("test.XcoAppSpaces.Core.WorkerContract/bla", true, false);
			Assert.AreEqual(0, workerRegistry.Workers.First().NumberOfConnections);
			//number of connect calls should be increased
			workerRegistry.Exists("test.XcoAppSpaces.Core.WorkerContract/bla", true, true);
			Assert.AreEqual(1, workerRegistry.Workers.First().NumberOfConnections);
		}

		[Test]
		[ExpectedException(typeof(XcoWorkerException))]
		public void TestAddWorker_WorkerCannotBeAddedTwice()
		{
			workerRegistry.AddWorker<WorkerContract>(new WorkerInfo<WorkerContract>(new WorkerContract(), null, null), "bla", PublishMode.Unpublished);
			workerRegistry.AddWorker<WorkerContract>(new WorkerInfo<WorkerContract>(new WorkerContract(), null, null), "bla", PublishMode.Unpublished);
		}

		[Test]
		[ExpectedException(typeof(XcoWorkerException))]
		public void TestAddWorkerProxy_WorkerCannotBeAddedTwice()
		{
			workerRegistry.AddWorkerProxy<WorkerContract>(new WorkerContract(), "bla", PublishMode.Unpublished, null, new WorkerProxyInfo(null, null, null, "myid", null, Guid.Empty, null, null));
			workerRegistry.AddWorkerProxy<WorkerContract>(new WorkerContract(), "bla", PublishMode.Unpublished, null, new WorkerProxyInfo(null, null, null, "myid", null, Guid.Empty, null, null));
		}

		[Test]
		public void TestAddWorker_WorkersWithDifferentNamesCanBeAdded()
		{
			workerRegistry.AddWorker<WorkerContract>(new WorkerInfo<WorkerContract>(new WorkerContract(), null, null), null, PublishMode.Unpublished);
			workerRegistry.AddWorker<WorkerContract>(new WorkerInfo<WorkerContract>(new WorkerContract(), null, null), "bla", PublishMode.Unpublished);
			workerRegistry.AddWorker<WorkerContract>(new WorkerInfo<WorkerContract>(new WorkerContract(), null, null), "bla2", PublishMode.Unpublished);
		}
	}
}
